import operator

import numpy as np
from os import listdir
from sklearn.neighbors import KNeighborsClassifier as KNN


def img2vector(fileName):
    returnVec = np.zeros((1, 1024))
    fr = open(fileName)
    for i in range(32):
        line = fr.readline()
        for j in range(32):
            returnVec[0, i * 32 + j] = int(line[j])
    return returnVec


def classify0(inX, dataSet, labels, k):
    lineCount = len(dataSet)
    dataSet = np.tile(inX, (lineCount, 1)) - dataSet
    dataSet = dataSet ** 2
    # sum(1)行相加
    disTance = dataSet.sum(axis=1)
    disTance = disTance ** 0.5
    sortedDistanceIndex = disTance.argsort()
    classCount = {}
    for i in range(k):
        label = labels[sortedDistanceIndex[i]]
        classCount[label] = classCount.get(label, 0) + 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

def handWritingTest():
    hwLabels = []
    trainingFileList = listdir('trainingDigits')
    m = len(trainingFileList)
    trainingMat = np.zeros((m, 1024))
    for i in range(m):
        fileName = trainingFileList[i]
        classNumber = int(fileName.split('_')[0])
        hwLabels.append(classNumber)
        trainingMat[i, :] = img2vector('trainingDigits/%s' % fileName)

    # 构造knn分类器
    neigh = KNN(n_neighbors=3, algorithm='auto')
    neigh.fit(trainingMat, hwLabels)
    testFileList = listdir('testDigits')
    errorCount = 0
    mTest = len(testFileList)
    for i in range(mTest):
        fileName = testFileList[i]
        classNumber = int(fileName.split('_')[0])
        vectorUnderTest = img2vector('testDigits/%s' % fileName)
        result = neigh.predict(vectorUnderTest)
        # result = classify0(vectorUnderTest,trainingMat,hwLabels,3)
        print("分类结果: %d\t 真实结果：%d" % (result, classNumber))
        if result != classNumber:
            errorCount += 1
    print("总共错了：%d 错误率：%f %%" % (errorCount, errorCount / mTest * 100))


if __name__ == "__main__":
    handWritingTest()

